@node Standard Pre-Scheme environment
@section Standard environment

@stindex prescheme
Pre-Scheme programs usually open the @code{prescheme} structure.  There
are several other structures built-in to Pre-Scheme as well, described
in the next section.  This section describes the @code{prescheme}
structure.

@menu

* Scheme bindings in Pre-Scheme::		Bindings from R5RS
* Tail call optimization in Pre-Scheme::
* Pre-Scheme bitwise manipulation::
* Compound Pre-Scheme data manipulation::
* Pre-Scheme error handling::
* Input & output in Pre-Scheme::
* Pre-Scheme access to C functions and macros::

@end menu

@node Scheme bindings in Pre-Scheme
@subsection Scheme bindings

Bindings for all the names specified here from R5RS Scheme are
available in Pre-Scheme.  The remainder of the sections after this one
detail Pre-Scheme specifics that are not a part of Scheme.

@deffn syntax define name value
@deffnx syntax define (name . argument-list) value
@deffnx syntax if condition consequent [alternate]
@deffnx syntax let ((name expression) @dots{}) body
@deffnx syntax let* ((name expression) @dots{}) body
@deffnx syntax and conjunct @dots{}
@deffnx syntax or disjunct @dots{}
@deffnx syntax cond cond-clause @dots{}
@deffnx syntax do ((name init-exp [step-exp]) @dots{}) (test-exp [return-exp]) body
These special forms & macros are all unchanged from their R5RS
specifications.
@end deffn

@deffn syntax define-syntax name transformer-expression [aux-names]
@deffnx syntax let-syntax ((name transformer-expression) @dots{}) body
@deffnx syntax letrec-syntax ((name transformer-expression) @dots{}) body
Pre-Scheme's macro facility is exactly the same as Scheme48's.
@var{Transformer-expression} may be either a @code{syntax-rules} or an
explicit renaming transformer, just as in Scheme48; in the latter case,
it is evaluated either in a standard Scheme environment or however the
@code{for-syntax} clause specified of the package in whose code the
transformer appeared.  For details on the extra @var{aux-names} operand
to @code{define-syntax}, @pxref{Explicit renaming macros}.
@end deffn

@deffn procedure not boolean @returns{} boolean
@deffnx procedure eq? value@suba{a} value@suba{b} @returns{} boolean
@deffnx procedure char=? char@suba{a} char@suba{b} @returns{} boolean
@deffnx procedure char<? char@suba{a} char@suba{b} @returns{} boolean
@deffnx procedure values value @dots{} @returns{} values
@deffnx procedure call-with-values producer consumer @returns{} values
@deffnx procedure current-input-port @returns{} input-port
@deffnx procedure current-output-port @returns{} output-port
These procedures are all unchanged from their R5RS specifications.
@end deffn

@deffn procedure + addend @dots{} @returns{} integer
@deffnx procedure - integer @returns{} integer
@deffnx procedure - minuend subtrahend @returns{} integer
@deffnx procedure * multiplicand @dots{} @returns{} integer
@deffnx procedure =  integer@suba{a} integer@suba{b} @returns{} boolean
@deffnx procedure <  integer@suba{a} integer@suba{b} @returns{} boolean
@deffnx procedure >  integer@suba{a} integer@suba{b} @returns{} boolean
@deffnx procedure <= integer@suba{a} integer@suba{b} @returns{} boolean
@deffnx procedure >= integer@suba{a} integer@suba{b} @returns{} boolean
@deffnx procedure min integer@sub{1} integer@sub{2} @dots{} @returns{} integer
@deffnx procedure max integer@sub{1} integer@sub{2} @dots{} @returns{} integer
@deffnx procedure abs integer @returns{} integer
@deffnx procedure quotient divisor dividend @returns{} integer
@deffnx procedure remainder divisor dividend @returns{} integer
@deffnx procedure expt base exponent @returns{} integer
These numerical operations are all unchanged from their R5RS
counterparts, except that they are applicable only to fixnums, not to
flonums, and they always return fixnums.
@end deffn

@node Tail call optimization in Pre-Scheme
@subsection Tail call optimization

@cindex Pre-Scheme tail call optimization
@cindex tail call optimization in Pre-Scheme
@cindex tail recursion in Pre-Scheme
@deffn syntax goto procedure argument @dots{}
The Pre-Scheme compiler can be forced to optimize tail calls, even
those it would not have otherwise optimized, by use of the @code{goto}
special form, rather than simple procedure calls.  In every respect
other than tail call optimization, this is equivalent to calling
@var{procedure} with the given arguments.  Note, however, that uses of
@code{goto} may cause code to blow up if the Pre-Scheme compiler had
reason not to optimize the tail call were it not for the @code{goto}:
it may need to merge the tail-called procedure into the caller's code.
@end deffn

@node Pre-Scheme bitwise manipulation
@subsection Bitwise manipulation

Pre-Scheme provides basic bitwise manipulation operators.

@deffn procedure bitwise-and integer@suba{a} integer@suba{b} @returns{} integer
@deffnx procedure bitwise-ior integer@suba{a} integer@suba{b} @returns{} integer
@deffnx procedure bitwise-xor integer@suba{a} integer@suba{b} @returns{} integer
@deffnx procedure bitwise-not integer @returns{} integer
Bitwise boolean logical operations.
@end deffn

@deffn procedure shift-left integer count @returns{} integer
@deffnx procedure arithmetic-shift-right integer count @returns{} integer
@deffnx procedure logical-shift-right integer count @returns{} integer
Three ways to shift bit strings: @code{shift-left} shifts @var{integer}
left by @var{count}, @code{arithmetic-shift-right} shifts @var{integer}
right by @var{count} arithmetically, and @code{logical-shift-right}
shifts @var{integer} right by @var{count} logically.
@end deffn

@node Compound Pre-Scheme data manipulation
@subsection Compound data manipulation

@cindex vectors in Pre-Scheme
@cindex Pre-Scheme vectors
@cindex strings in Pre-Scheme
@cindex Pre-Scheme strings
@cindex Pre-Scheme memory management
@cindex memory management in Pre-Scheme
Pre-Scheme has somewhat lower-level vector & string facilities than
Scheme, with more orientation towards static typing.  It also provides
a statically typed record facility, which translates to C structs,
though not described here, as it is not in the @code{prescheme}
structure; @pxref{Pre-Scheme record types}.

@deffn procedure make-vector length init @returns{} vector
@deffnx procedure vector-length vector @returns{} integer
@deffnx procedure vector-ref vector index @returns{} value
@deffnx procedure vector-set! vector index value @returns{} unit
Vectors in Pre-Scheme are almost the same as vectors in regular Scheme,
but with a few differences.  @code{Make-vector} initializes what it
returns with null pointers (see below); it uses the @emph{required}
(unlike Scheme) @var{init} argument only to determine the type of the
vector: vectors are statically typed; they can contain only values that
have the same static type as @var{init}.  @code{Vector-length} is
available only at the top level, where calls to it can be evaluated at
compile-time; vectors do not at run-time store their lengths.  Vectors
must also be explicitly deallocated.

@strong{Warning:} As in C, there is @emph{no} vector bounds checking at
run-time.
@end deffn

@deffn procedure make-string length @returns{} string
@deffnx procedure string-length string @returns{} integer
@deffnx procedure string-ref string index @returns{} char
@deffnx procedure string-set! string index char @returns{} unit
Strings in Pre-Scheme are the nearly same as strings in R5RS Scheme.
The only three differences here are that @code{make-string} accepts
exactly one argument, strings must be explicitly deallocated, and
strings are @code{nul}-terminated: @code{string-length} operates by
scanning for the first ASCII @code{nul} character in a string.

@strong{Warning:} As in C, there is @emph{no} string bounds checking at
run-time.
@end deffn

@deffn procedure deallocate pointer @returns{} unit
Deallocates the memory pointed to by @code{pointer}.  This is necessary
at the end of a string, vector, or record's life, as Pre-Scheme data
are not automatically garbage-collected.
@end deffn

@deffn procedure null-pointer @returns{} null-pointer
@deffnx procedure null-pointer? pointer @returns{} boolean
@code{Null-pointer} returns the distinguished null pointer object.  It
corresponds with @code{0} in a pointer context or @code{NULL} in C.
@code{Null-pointer?} returns true if @var{pointer} is a null pointer,
or false if not.
@end deffn

@node Pre-Scheme error handling
@subsection Error handling

Pre-Scheme's method of error handling is similar to the most common one
in C: error codes.  There is an enumeration @code{errors} of some error
codes commonly and portably encountered in Pre-Scheme.

@defvr {enumeration} errors
@lisp
(define-enumeration errors
  (no-errors
   parse-error
   file-not-found
   out-of-memory
   invalid-port))@end lisp
Each enumerand has the following meaning:

@table @code
@item (enum errors no-errors)
Absence of error: success.

@item (enum errors parse-error)
Any kind of parsing error.  The Scheme48 VM uses this when someone
attempts to resume a malformed suspended heap image.

@item (enum errors file-not-found)
Used when an operation that operates on a file given a string filename
found that the file for that filename was absent.

@item (enum errors out-of-memory)
When there is no more memory to allocate.

@item (enum errors invalid-port)
Unused.
@end table
@end defvr

@deffn procedure error-string error-status @returns{} string
Returns a string describing the meaning of the @code{errors} enumerand
@var{error-status}.
@end deffn

@deffn procedure error message irritant @dots{}
Signals a fatal error with the given message & related irritants and
halts the program.  On Unix, the program's exit code is -1.
@end deffn

@node Input & output in Pre-Scheme
@subsection Input & output

Pre-Scheme's I/O facilities are somewhat different from Scheme's, given
the low level and the static type strictness.  There is no exception
mechanism in Pre-Scheme; everything is maintained by returning a status
token, as in C.  Pre-Scheme's built-in I/O facilities are buffered.
@footnote{Scheme48's VM does not use Pre-Scheme's built-in I/O
facilities to implement @embedref{Channels, channels} --- it builds its
own lower-level facilities that are still OS-independent, but, because
they're written individually for different OSs, they integrate better
as low-level I/O channels with the OS.  On Unix, the Scheme48 VM uses
file descriptors; Pre-Scheme's built-in I/O uses @code{stdio}.
Scheme48's VM uses Pre-Scheme's built-in I/O only to read heap images.}
(@pxref{Low-level Pre-Scheme memory manipulation}, for two other I/O
primitives, @code{read-block} & @code{write-block}, for reading &
writing blocks of direct memory.)

@deffn procedure open-input-file filename @returns{} [port status]
@deffnx procedure open-output-file filename @returns{} [port status]
@deffnx procedure close-input-port input-port @returns{} status
@deffnx procedure close-output-port output-port @returns{} status
@code{Open-input-file} & @code{open-output-file} open ports for the
given filenames.  They each return two values: the newly open port and
an @code{errors} enumerand status.  Users of these procedures should
always check the error status before proceeding to operate with the
port. @code{Close-input-port} & @code{close-output-port} close their
port arguments and return the @code{errors} enumerand status of the
closing.
@end deffn

@deffn procedure read-char input-port @returns{} [char eof? status]
@deffnx procedure peek-char input-port @returns{} [char eof? status]
@deffnx procedure read-integer input-port @returns{} [integer eof? status]
@code{Read-char} reads & consumes a single character from its
@var{input-port} argument.  @code{Peek-char} reads, but does not
consume, a single character from @var{input-port}.  @code{Read-integer}
parses an integer literal, including sign.  All of these also return
two other values: whether or not the file is at the end and any
@code{errors} enumerand status.  If any error occurred, the first two
values returned should be ignored.  If @var{status} is @code{(enum
errors no-errors)}, users of these three procedures should then check
@var{eof?}; it is true if @var{input-port} was at the end of the file
with nothing more left to read and false otherwise.  Finally, if both
@var{status} is @code{(enum errors no-errors)} and @var{eof?} is false,
the first value returned may be safely used.
@end deffn

@deffn procedure write-char char output-port @returns{} status
@deffnx procedure newline output-port @returns{} status
@deffnx procedure write-string string output-port @returns{} status
@deffnx procedure write-integer integer output-port @returns{} status
These all write particular elements to their @var{output-port}
arguments.  @code{Write-char} writes individual characters.
@code{Newline} writes newlines (line-feed, or ASCII codepoint 10, on
Unix).  @code{Write-string} writes the contents of @var{string}.
@code{Write-integer} writes an ASCII representation of @var{integer} to
port, suitable to be read by @code{read-integer}.  These all return an
@code{errors} enumerand status.  If it is @code{no-errors}, the write
succeeded.
@end deffn

@deffn procedure force-output output-port @returns{} status
Forces all buffered output in @var{output-port}.  @var{Status} tells
whether or not the operation was successful.
@end deffn

@node Pre-Scheme access to C functions and macros
@subsection Access to C functions and macros

@deffn syntax external c-name ps-type @returns{} procedure
Special form for accessing C functions & macros.  Calls in Pre-Scheme to
the resulting procedure are compiled to calls in C to the function or
macro named by @var{c-name}, which should be a string.  @var{PS-type} is
the @embedref{Pre-Scheme type specifiers, Pre-Scheme type} that the
procedure should have, which is necessary for type inference.
@end deffn
